﻿using System;
using System.Collections.Generic;
using System.Web;
using System.Web.Routing;
using ManagedUIFlow.Infrastructure.Commands;
using ManagedUIFlow.Infrastructure.Flows;
using ManagedUIFlow.Model;
using Moq;
using Xunit;

namespace ManagedUIFlow.Specs.Infrastructure.Commands
{
    public class DefaultCommandFactorySpecs
    {
        private readonly RequestContext _requestContext;
        private readonly Mock<HttpContextBase> _contextMock;
        private readonly List<Flow> _flows;

        public DefaultCommandFactorySpecs()
        {
            _contextMock = new Mock<HttpContextBase>();
            _requestContext = new RequestContext(_contextMock.Object, new RouteData());
            _flows = new List<Flow>
                         {
                             new Flow("foo", "bar", RedirectBehavior.Manual, "")
                                 {
                                     Navigations = new List<Navigation>
                                                       {
                                                           new Navigation("foobar", NavigationType.RenderView)
                                                               {
                                                                   Transitions = new List<Transition>
                                                                                     {
                                                                                         new Transition("travel",
                                                                                                        "foobar")
                                                                                     }
                                                               }
                                                       }
                                 }
                         };
        }

        [Fact]
        public void CreatingCommandWhenContextAndFlowIsNull_Throws()
        {
            var factory = new DefaultCommandFactory();

            Assert.Throws<ArgumentNullException>(() => ((ICommandFactory) factory).CreateCommand(null, null));
        }

        [Fact]
        public void CreateCommandForViewNavigation_ReturnsFlowView()
        {
            var factory = new DefaultCommandFactory();
            var flow = new ManagedFlow(Guid.NewGuid(), "foo", "foobar", RedirectBehavior.Manual, string.Empty);
            factory.Flows = _flows;

            var command = factory.CreateCommand(_requestContext, flow);

            Assert.IsType(typeof(FlowView), command);
        }

        [Fact]
        public void CommandForInvalidNavigation_ReturnsNull()
        {
            var factory = new DefaultCommandFactory();
            var flow = new ManagedFlow(Guid.NewGuid(), "search", "foobar", RedirectBehavior.Manual, string.Empty);
            factory.Flows = _flows;

            var command = factory.CreateCommand(_requestContext, flow);

            Assert.Null(command);
        } 

        [Fact]
        public void CommandFactoryWithDisposableCommand_Disposes()
        {
            var factory = new DefaultCommandFactory();
            var mockCommand = new Mock<ICommand>();
            var mockDisposable = mockCommand.As<IDisposable>();
            mockDisposable.Setup(d => d.Dispose()).Verifiable();

            factory.ReleaseCommand(mockCommand.Object);

            mockDisposable.Verify();
        }

    }


}
